import { wxappConfigs } from '../scretConfig'
import { ApiProxy } from './ApiProxy'

type APIQueryArgCollection = ApiTypes.APIQueryArgCollection
type APIBodyArgCollection = ApiTypes.APIBodyArgCollection
type WxApiBaseResult = ApiTypes.WxApiBaseResult

function asyncWrap<T extends WxApiBaseResult>(method: 'GET' | 'POST', path: string,
                                              urlArgs?: APIQueryArgCollection, bodyArgs?: APIBodyArgCollection): Promise<T> {
  const proxy = new ApiProxy<T>(method, path, urlArgs, bodyArgs)
  return new Promise<T>((ok, fail) => {
    proxy.success((res) => {
      const { errcode, errmsg } = res
      if (errcode !== 0) {
        return fail({ errcode, errmsg })
      }
      return ok(res)
    }).fail(() => {
      fail({ errcode: 50050, errmsg: 'http error' })
    })
  })
}

export namespace api {

  function get<T extends WxApiBaseResult>(
    path: string,
    urlArgs?: APIQueryArgCollection
  ): Promise<T> {
    return asyncWrap('GET', path, urlArgs)
  }

  function post<T extends WxApiBaseResult>(
    path: string,
    urlArgs?: APIQueryArgCollection,
    bodyArgs?: APIBodyArgCollection
  ): Promise<T> {
    return asyncWrap('POST', path, urlArgs, bodyArgs)
  }

  export function testPost() {
    return post<WxApiBaseResult>('/login')
  }

  export function testGet() {
    return get<WxApiBaseResult>('/login')
  }

  export function login(code: string) {
    const query = {
      ...wxappConfigs,
      grantType: 'authorization_code',
      jsCode: code
    }
    return get<WxApiBaseResult & WxApiDataResponse.Login>('/sns/jscode2session', query)
  }

  export function getAccessToken() {
    const query = {
      ...wxappConfigs,
      grantType: 'client_credential',
    }
    return get<WxApiBaseResult & { accessToken: string, expiresIn: TimestampSec }>('/cgi-bin/token', query)
  }

}

export default api
